モデルが発する帯電エフェクト
左上のSpawn
Spawn内の各ノードの説明
① Constant Spawn Rate 指定した数のパーティクルを1秒に生成されるような生成処理を行う → 1秒に一回生成するのではなく。毎フレームdeltaTimeに応じて生成しているため一秒にrate数分生成されるということ
② Periodic Burst (定期的) ※ 後述のSingle Burstの Repeatを Periodic に変更するとノード名が変化します 定期的にパーティクルの数を生成。 瞬間的に生成する。 Delayで指定した時間待機(秒)。経過後次のパーティクルを生成
■ Spawn Mode
- Constant
- 固定数を生成
- Random
- X~Y間のランダム
■ Delay Mode
- Constant
- 固定秒数待機
- Random
- X~Y間のランダム
③ Single Burst 一度だけ瞬間的に生成
その他 Set SpawnEvent Lifetime Lifetimeを動的に変更する これは Initialize にある Iherit Source Liefetime が利用しています。つまりSpawnに設定されている値を利用してパーティクルの生存期間を指定。
右の Single Burst は 0.3 が指定されているため、ここで生成されたパーティクルは左のSpawnよりも 0.1秒寿命が短いということになります
Update
Update部分は長いですがひとつひとつ見ていきます。上から順番
まずよく見ると右上が WORLD となっています。 ここは Space を変更する箇所で、クリックするたびに Local ↔ World と変化します(わかりにくい)
Space
Localの場合は親オブジェクトのローカル座標で動かすことになり、親が動くとパーティクルも動く Worldの場合は放出されたパーティクルは親に追従しません
① SetPosition
① SkinndMeshRendererプロパティをGet
② SkinndMeshRendererから頂点数を取得
③、④ RundomNumberは [Min-Max] 間のランダム値を返すものでそれぞれ [0-②] [②-1] の数を獲得。 設定は PerParticle となっており、パーティクル毎にランダムな値が返されます
ランダムで求めた値を Sample Skinned Mesh に接続
Sample Mesh
https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@12.1/manual/Operator-SampleMesh.html 引数の SkinnedMesh の頂点から Position, Color, TexCoord0, Normal,,, などなど 情報を返却してくれるありがたいノードです
Vertexに値が設定されている頂点をサンプリングします。今回はランダムの出力値を設定しているため、ランダムな頂点をサンプリングします
Positionが右に伸び、 Position と繋がり、そのPositionのベクトル座標に固定値を Add しているノードが存在
Position を Position につなげているのが疑問ですが、よくみると W と書かれているのがわかります これは座標をワールドSpaceに変換していることを表しているものと思われます
その値に対し補正用に固定値をAddし、最終的に Sample Bezier に接続
Sample Bezier
https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@12.1/manual/Operator-SampleBezier.html ベジェ曲線を生成するノードとなり、4つの点と現在の進行状況を表す t で曲線を求めます
↓ 公式動画
t は Age Over Lifetime が接続されています
Age Over Lifetime
パーティクルの残り寿命を [0-1] 範囲に収めて返すノードですね つまり、生まれたてはAに近く、死にかけはDの点に近くなります。
この曲線で電撃が体にはっているような演出を表していました。
つまり①のSetPositionが行っていたことは
- パーティクルのモデルの頂点をランダムに選出
- ワールド座標系のPositionを抽出
- 2点間を直線ではなく曲線で書くことで電撃感が出る位置を求めている
ということでした
② SetPosition
①もSetPosition,②もSetPosition。やってることはシンプルで
Get Attribute: position [Current] は①で求めた座標を取得しています。 RootTransform はプロパティでうけとる Transform の Posotion です。 TransformのPositionに対して①のPositionを足し合わせて補正しています。
公式の説明がわかりやすい https://docs.unity3d.com/ja/Packages/com.unity.visualeffectgraph@10.7/manual/Operator-Transform(Position).html
RootTransformはVFXPropertyBinderで、モデルのHip(モデルの中心点となる箇所)が指定されており、 エフェクトとモデルのズレを矯正してくれています(このスクリプトを消して実行してみると変化がわかりやすい)
③ Set Alive
Alive プロパティの設定。 Aliveのチェックを外すとそのパーティクルは即死します
モデルに合わせたマスクテクスチャを利用していました こちらを始点と終点のUVでサンプリングして、 Compare ノードで比較。 Greater が設定されているため Left (サンプリング側) が 0.85 より大きければ 1 を返します。 その双方を And でビット演算した結果を Set Aliveに利用しています
つまり、どちらも 0.85以上の出力をしている場合は問題なくパーティクルを生成しますが、それ以外はパーティクルを発生させません マスクを見ると
目や鼻、口などの部分には色が乗っておらず、電撃ポイントの対象外としているようです
続いて、これらの結果を GPU Event で別の処理に移行しています
このように処理を別に書きたい場合に GPU Event で前シーケンスの結果を利用する形を取っています
まずはIntializeをみます。 ブロックは Initialize Particle Strip ノードとなっています。
Particle Strip は公式の動画がとてもわかり易いです https://www.youtube.com/watch?v=gdb9zvHh3r0
画像で一発で説明すると こういう事が可能になるようです つまり、生成したパーティクルの動きを線でつなげて帯状に描画することが可能になる。
なので、まずはUpdateで動きを表し、次のシーケンスでそれらをつなげて帯として描画する。という二段階の処理を構築されています
これで雷の帯を表しています 内に持っているノードは
- Inherit Source Position (Set)
- 前の結果の座標を利用する
- Set Liefetime
- 生存時間
です。
そして次のブロック、Update Particle Strip は Turbulence ノードがついています
こちらも公式の説明がわかりやすいです https://docs.unity3d.com/ja/Packages/com.unity.visualeffectgraph@10.7/manual/Block-Turbulence.html
速度に合わせて乱流を生むノードとなっており、動きをつけるときにとても重宝するノード 今回は雷の動きのゆらぎに利用されています
最後は Output ParticleStrip Quad
こちらはノードがいくつかひっついています
Orient: Face Camera Position
https://docs.unity3d.com/Packages/com.unity.visualeffectgraph@12.1/manual/Block-Orient.html 公式によると Face Camera Posotion は常にカメラ方向にパーティクルを向けるようにします
Subpixel Anti-Aliasing
パーティクルの角度、拡縮によってパーティクルが見えなくならないように補正をしてくれるノードのようです ON/OFFで違いを見ればわかりやすく、OFFにすると帯状のエフェクトの中が途切れるのが確認できます
Set Size over Life
生存時間に応じてパーティクルのサイズをカーブで制御
SetColor
色の設定
Set Alpha over Life 生存期間に応じてパーティクルのサイズをカーブで制御
以上で左側の処理を見ていけました 続いて右側の処理を見ていきます
Spawn
まずはSpawn郡
periodic Burst, SIngle Burstは前回と同じで 真ん中のSpawnに Loop Duration と Loop Count が設定されています
Loop Duration でループ間隔、 Loop Count でループ回数
Iniialize
上のブロックから見ていきます
①Set Position 同じくSkinnedMeshRendererの頂点数を RandomNumber [0-VertexCount] でランダム頂点を取り出し、 Position を設定しています
②Set Postiion ①のSetPostiionで設定したPositionとプロパティTrasnfromのPositionを足し合わせています
③Set Velocity Random(Per-component) パーティクルの速度をランダムに設定
③ Set LIefetime Ranfom (Uniform) 生存時間をランダムに決定
上記ランダムの Per-component, Uniform については公式の動画で詳細が説明されています https://learning.unity3d.jp/6582/
最後に描画処理のOutputでうが、特に変わったことは無くそのまま表示しています
以上でモデルを這う雷の表現のサンプルでした こちらのエフェクトは視覚的にもインパクトが有り使いやすそうです